#include "AgentFrame.h"
#include "ControllerConnection.h"
#include "Settings.h"
#include "ReservedJobs.h"

ACE_THR_FUNC_RETURN ReactorThread(void *arg) {

    ACE_Reactor *reactor = (ACE_Reactor *) arg;
    reactor->run_reactor_event_loop();

    return 0;
}

int ACE_TMAIN (int argc, ACE_TCHAR * argv[])
{

#ifndef _TEST_
	ACE_Process_Mutex mu(AGENT_NAME);
	if( mu.tryacquire() != 0)
	{
		printf("You can't load multiple agents in one machine!\n");
		return -1;
	}
#endif
	
	if(!Settings::Start())
	{
		return -1;
	}

	LOG::Start(); 

	if(Settings::GetSettings()->LOCAL_ADDR.length() == 0)
	{
		printf("[agent] can not get local addr\n");
		return -1;
	}

	char active = 'F';
	_DB_RESULT db_result = DBInterface::GetAgentMode(Settings::GetSettings()->RENDERER_ID , Settings::GetSettings()->LOCAL_ADDR , active);
	if(_DB_SUCCESS != db_result)
	{
		char buf[1024];
		sprintf(buf , "DB::::GetAgentMode  :%d ,  %s" ,db_result , Settings::GetSettings()->LOCAL_ADDR.c_str());
		printf("%s\n" , buf);
		LOG::PushProcessLog(_ERROR, buf);

		return -1;
	}
			
	if(active == 'F' || active == 'f')
	{
		char buf[1024];
		sprintf(buf , "this addr[%s] is not registered or inactive mode\n" , Settings::GetSettings()->LOCAL_ADDR.c_str());
		printf("%s\n" , buf);
		LOG::PushProcessLog(_ERROR, buf);

		return -1;
	}

	db_result = DBInterface::ClearProcessingJobs(Settings::GetSettings()->RENDERER_ID , Settings::GetSettings()->LOCAL_ADDR);
	if(_DB_SUCCESS != db_result)
	{
		char buf[1024];
		sprintf(buf , "DB::::ClearProcessingJobs  :%d ,  %s" ,db_result , Settings::GetSettings()->LOCAL_ADDR.c_str());
		printf("%s\n" , buf);
		LOG::PushProcessLog(_ERROR, buf);

		return -1;
	}


	printf("\n######################## First Setting Values ####################\n");
	printf("%s" , Settings::GetSettings()->dump().c_str());
	printf("\n###################################################################\n");
	printf("LOCAL ADDR : %s\n" , Settings::GetSettings()->LOCAL_ADDR.c_str());
	printf("CONTROLLER_ADDR : %s\n" , Settings::GetSettings()->CONTROLLER_ADDR.c_str()); 
	printf("#######################################################################\n");


	LOG::PushProcessLog(_REQUIRED , "START");
	printf("[agent] started\n");

	PROCESS cp;
	cp.activate();

	JOB_MONITOR::Start(); 
	ReservedJobs::Start();

	
	PROCESS::DeleteTempFiles();

    ACE_TP_Reactor tpReactor;
    ACE_Reactor reactor(&tpReactor);
	ACE_Thread_Manager::instance()->spawn_n((int)ACE_OS::num_processors() , ReactorThread, &reactor);

	if(!ControllerWorker::Start(&reactor) )
	{
		return -1;
	}

#ifndef ACE_WIN32
	PROCESS::InitSignal();
#endif

	ACE_Reactor::instance ()->run_reactor_event_loop ();

	LOG::PushProcessLog(_REQUIRED , "END");
	printf("[agent] terminated\n");

	PROCESS::Clear(); 
	Renderer::Finish();

	exit(0);

	LOG::Stop();
	ReservedJobs::Stop();
	JOB_MONITOR::Stop(); 

	Settings::Release();
	DBInterface::DeleteAllConnections();

	return 0;

}	


